﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using Autofac;
using CacheManager.Core;
using CacheManager.Redis;
using BSF.Log;
using System.IO;
using System.Web.Hosting;

namespace BSF.Framework
{
    public class AppBootstrap
    {
        /// <summary>
        /// lazy加载单例模式
        /// </summary>
        private static readonly Lazy<AppBootstrap> Lazy = new Lazy<AppBootstrap>(() => new AppBootstrap());

        /// <summary>
        /// 是否已启动完成
        /// </summary>
        public bool IsStartCompleted { get; private set; }

        /// <summary>
        /// WebSiteBootstrap的单例
        /// </summary>
        public static AppBootstrap Instance { get { return Lazy.Value; } }

        protected AppBootstrap()
        {
        }

        public void Start(params Assembly[] contrllerAssemblys)
        {
            //var allAssemblies = Loader.GetAllAssemblies();
            //CommLog.Write("数量first:" + allAssemblies.Count);
            //Start(allAssemblies, contrllerAssemblys);
            Start(null, contrllerAssemblys);
        }

        private void Start(IEnumerable<Assembly> allAssemblies, params Assembly[] contrllerAssemblys)
        {
            var builder = new ContainerBuilder();
            //var allAssembliesArray = allAssemblies.ToArray();
            #region 注册 CacheManager
            var configFile = MapPath("~/config/CacheManager.config");

            // have to load the configuration manually because the file is not avialbale to the default ConfigurtaionManager
            RedisConfigurations.LoadConfiguration(configFile, RedisConfigurationSection.DefaultSectionName);
            var cacheConfig = ConfigurationBuilder.LoadConfigurationFile(configFile, "defaultCache");
            builder.RegisterGeneric(typeof(BaseCacheManager<>))
                .WithParameters(new[]
                {
                    //new TypedParameter(typeof(string), "defaultCache"),
                    new TypedParameter(typeof(ICacheManagerConfiguration), cacheConfig)
                })
                .As(typeof(ICacheManager<>))
                .SingleInstance();
            #endregion
            
            BeginRegisterIoc(builder, contrllerAssemblys);

            IContainer iocContanier = null;
            try
            {
                iocContanier = builder.Build();
            }
            catch (Exception ex)
            {
                ErrorLog.Write("严重错误：Ioc Build出错", ex);
                throw ex;
            }
            //设置基础Ioc服务locator
            Microsoft.Practices.ServiceLocation.ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(iocContanier));

            AfterRegisterIoc(iocContanier, contrllerAssemblys);

            IsStartCompleted = true;
        }
        protected virtual void BeginRegisterIoc(ContainerBuilder builder, params Assembly[] contrllerAssemblys)
        {
        }

        protected virtual void AfterRegisterIoc(IContainer container, params Assembly[] contrllerAssemblys)
        {
        }
        public string MapPath(string path)
        {
            if (HostingEnvironment.IsHosted)
            {
                return HostingEnvironment.MapPath(path);
            }
            else
            {
                //Loader = new FolderAssemblyFinder(System.AppDomain.CurrentDomain.BaseDirectory); 
                var root = System.AppDomain.CurrentDomain.BaseDirectory;//Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                if (path.StartsWith("~/"))
                {
                    path = path.Substring(2, path.Length - 2);
                }
                var resultPath = Path.Combine(root, path);
                return resultPath;
            }
        }

    }
}
